package com.leyou.order.service;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LeYouException;
import com.leyou.item.pojo.Sku;
import com.leyou.order.client.AddressClient;
import com.leyou.order.client.GoodsClient;
import com.leyou.order.dto.AddressDTO;
import com.leyou.order.dto.CartDTO;
import com.leyou.order.dto.OrderDTO;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.enums.PayState;
import com.leyou.order.interceptor.UserInterceptor;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.mapper.OrderStatusMapper;
import com.leyou.order.pojo.Order;
import com.leyou.order.pojo.OrderDetail;
import com.leyou.order.pojo.OrderStatus;
import com.leyou.order.utils.PayWxHelper;
import com.leyou.utils.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Transactional(rollbackFor = Exception.class)
@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;


    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private PayWxHelper payWxHelper;


    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(OrderDTO orderDTO) throws Exception {

        // 1. 新增订单
        Order order = new Order();
        // 1.1 订单编号， 基本信息
        long orderId = idWorker.nextId();
        order.setOrderId(orderId);
        order.setCreateTime(new Date());
        order.setPaymentType(orderDTO.getPaymentType());
        // 1.2 用户信息
        UserInfo userInfos = UserInterceptor.getUserInfos();
        order.setUserId(userInfos.getId());
        order.setBuyerNick(userInfos.getUsername());
        order.setBuyerRate(false);
        // 1.3 收货人地址
        // 获取收货人信息
        AddressDTO addr = AddressClient.findById(orderDTO.getAddressId());
        order.setReceiver(addr.getName());
        order.setReceiverAddress(addr.getAddress());
        order.setReceiverCity(addr.getCity());
        order.setReceiverDistrict(addr.getDistrict());
        order.setBuyerRate(addr.getIsDefault());
        order.setReceiverMobile(addr.getPhone());
        order.setReceiverState(addr.getState());

        // 金额
        List<CartDTO> carts = orderDTO.getCarts();

        Map<Long, Integer> numMap = orderDTO.getCarts().stream().collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));

        List<Long> ids = carts.stream().map(CartDTO::getSkuId).collect(Collectors.toList());

        List<Sku> skuList = goodsClient.querySkuBySpuIds(ids);
        // 准备 orderDetailList 集合
        ArrayList<OrderDetail> orderDetails = new ArrayList<>();

        long totalPay = 0L;
        for (Sku sku : skuList) {
            // 计算商品总价
            totalPay += sku.getPrice() * numMap.get(sku.getId());


            // 封装OrderDetail
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setImage(StringUtils.substringBefore(sku.getImages(), ","));
            orderDetail.setNum(numMap.get(sku.getId()));
            orderDetail.setOrderId(orderId);
            orderDetail.setOwnSpec(sku.getOwnSpec());
            orderDetail.setPrice(sku.getPrice());
            orderDetail.setSkuId(sku.getPrice());
            orderDetail.setTitle(sku.getTitle());
            orderDetails.add(orderDetail);
        }
        order.setTotalPay(totalPay);
        // 实付金额 + 邮费 -- 优惠金额
        order.setActualPay(totalPay + order.getPostFee() - 0);

        // order 写入数据库
        int orderResult = orderMapper.insertSelective(order);
        if (orderResult != 1) {
            log.error("[创建订单] 创建订单失败， orderId:{}", orderId);
            throw new LeYouException(ExceptionEnum.CREATE_ORDER_ERROR);
        }
        // 2. 新增订单详情
        int count = orderDetailMapper.insertList(orderDetails);
        if (count != orderDetails.size()) {
            log.error("[创建订单] 创建订单详情失败， orderId:{}", orderId);
            throw new LeYouException(ExceptionEnum.CREATE_ORDER_ERROR);
        }
        // 3. 新增订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setCreateTime(order.getCreateTime());
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.UN_PAY.getCode());
        orderResult = orderStatusMapper.insert(orderStatus);
        if (orderResult != 1) {
            log.error("[创建订单] 创建订单状态失败， orderId:{}", orderId);
            throw new LeYouException(ExceptionEnum.CREATE_ORDER_ERROR);
        }
        // 减少库存
        List<com.leyou.item.dto.CartDTO> cartList = new ArrayList();
        for (CartDTO cart : carts) {
            com.leyou.item.dto.CartDTO cartDTO = new com.leyou.item.dto.CartDTO();
            BeanUtils.copyProperties(cart, cartDTO);
            cartList.add(cartDTO);
        }
        goodsClient.decreaseStock(cartList);

        return orderId;
    }

    /**
     * 根据订单Id 查询 订单
     *
     * @param id
     * @return
     */
    public Order queryOrderById(Long id) {
        // 查询订单
        Order order = orderMapper.selectByPrimaryKey(id);
        if (order == null) {
            // 不存在
            throw new LeYouException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        // 查询订单详情
        OrderDetail orderDetail = new OrderDetail();
        List<OrderDetail> orderDetails = orderDetailMapper.select(orderDetail);
        if (CollectionUtils.isEmpty(orderDetails)) {
            throw new LeYouException(ExceptionEnum.ORDER_DETAIL_NOT_FOUND);
        }
        // 查询订单状态
        OrderStatus orderStatus = orderStatusMapper.selectByPrimaryKey(id);
        if (order == null) {
            // 不存在
            throw new LeYouException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }
        order.setOrderDetails(orderDetails);
        order.setOrderStatus(orderStatus);
        return order;
    }


    /**
     * @param orderId
     * @return
     */
    public String createPayUrl(Long orderId) {
        // 查询订单
        Order order = queryOrderById(orderId);
        // 支付金额
        Long actualPay = order.getActualPay();
        // 判断订单状态
        Integer status = order.getOrderStatus().getStatus();
        if (status != OrderStatusEnum.UN_PAY.getCode()) {
            // 订单状态异常
            throw new LeYouException(ExceptionEnum.ORDER_STATUS_ERROR);
        }

        // 商品描述
        String title = order.getOrderDetails().get(0).getTitle();

        String url = payWxHelper.createOrder(orderId, 1L, "红米手机Note Plus5 ");

        return url;
    }


    /**
     * @param result
     */
    @Transactional(rollbackFor = Exception.class)
    public void handleNotify(Map<String, String> result) {
        // 数据校验
        payWxHelper.isSuccess(result);
        // 签名验证
        payWxHelper.isValidSign(result);
        // 校验金额
        String totalFeeStr = result.get("total_fee");
        String orderId = result.get("out_trade_no");
        if (StringUtils.isEmpty(totalFeeStr) || StringUtils.isEmpty(orderId)) {
            throw new LeYouException(ExceptionEnum.INVALID_ORDER_PARAM);
        }
        // 获取结果中的金额
        Long totalFee = Long.valueOf(totalFeeStr);
        // 获取订单金额
        Long orderNo = Long.valueOf(orderId);
        Order order = orderMapper.selectByPrimaryKey(orderNo);
        if (totalFee != order.getActualPay()) {
            // 金额不符
            throw new LeYouException(ExceptionEnum.INVALID_ORDER_PARAM);
        }
        // 修改订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setStatus(OrderStatusEnum.PAYED.getCode());
        orderStatus.setPaymentTime(new Date());
        orderStatus.setOrderId(orderNo);

        int count = orderStatusMapper.updateByPrimaryKeySelective(orderStatus);
        if (count != 1) {
            throw new LeYouException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
        }

        log.info("[微信订单回调] 订单支付成功！ 订单编号：{}", orderNo);
    }


    /**
     * 根据订单id 查询订单状态
     *
     * @param orderId
     * @return
     */
    public PayState queryOrderStatus(Long orderId) {
        // 查询订单状态
        OrderStatus orderStatus = orderStatusMapper.selectByPrimaryKey(orderId);
        if (orderStatus == null) {
            throw new LeYouException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }
        // 判断是否支付
        if (orderStatus.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
            // 如果已经支付， 真的是 已经支付
            return PayState.SUCCESS;
        }
        // 如果未支付， 但其实不一定是未支付， 必须去微信查询支付状态
        return payWxHelper.queryPayStatus(orderId);

    }
}
